package it.unica.informatica.enotes.adapter;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.method.DigitsKeyListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import it.unica.informatica.enotes.R;
import it.unica.informatica.enotes.manager.AttachmentsStoringManager;
import it.unica.informatica.enotes.notes.AttachmentItem;
import it.unica.informatica.enotes.notes.Note;

/**
 * This class manages a single row of the ListView that show the list of all the attachments for a note
 *
 * @author Mirko Marras
 * @version 1.0
 */
public class MultimediaItemAdapter extends BaseAdapter {

   private Context notesActivity;
   private Note currentNote;
   private Button tabButton;
   private boolean editState;
   private List<AttachmentItem> attachments;
   private LayoutInflater inflater;

   /**
    * Construct a new adapter to manage the list of all the attachments associated to the current note
    *
    * @param notesActivity The activity that manages the data of the current note
    * @param currentNote   The note that the adapter represents
    * @param tabButton     The tab button associated to the attachments list
    * @param editState     The EditState for the current note: ONLY VIEW or EDIT
    * @param attachments   The list of all the attachments associated to the current note
    */
   public MultimediaItemAdapter(Activity notesActivity, Note currentNote, Button tabButton, boolean editState, List<AttachmentItem> attachments) {
      this.notesActivity = notesActivity;
      this.currentNote = currentNote;
      this.attachments = attachments;
      this.tabButton = tabButton;
      this.editState = editState;
      this.inflater = (LayoutInflater) notesActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   }

   /**
    * Get the number of the attachments associated to the current note
    *
    * @return The number of the attachments associated to the current note
    */
   @Override
   public int getCount() {
      return attachments.size();
   }

   /**
    * Get the attachment associated to the position in the list
    *
    * @param position The position of the attachment to retrieve
    * @return The row of the list associated to the position
    */
   @Override
   public AttachmentItem getItem(int position) {
      return attachments.get(position);
   }

   /**
    * Remove an attachment at the position
    *
    * @param from The position of the attachment to remove
    */
   public void remove(int from) {
      attachments.remove(from);
   }

   /**
    * Insert an attachment at the position
    *
    * @param item The attachment to insert
    * @param to   The position where insert the attachment
    */
   public void insert(AttachmentItem item, int to) {
      attachments.add(to, item);
   }

   /**
    * Get the ID of the attachment associated to the position in the list
    *
    * @param position The position of the attachment ID to retrieve
    * @return The tag ID of the attachment associated to the position
    */
   @Override
   public long getItemId(int position) {
      return position;
   }

   /**
    * This class contains the view objects associated with the views of the layout
    *
    * @author Mirko Marras
    * @version 1.0
    */
   private class RowLayout {
      ImageView attachmentThumbnails;

      TextView attachmentName;
      TextView attachmentType;

      ImageView deleteButton;
      ImageView editButton;
   }

   /**
    * Construct a view that represents a row in the list of all the attachments for the current note
    *
    * @param position    The position in the list for the current attachment
    * @param convertView The view to which the current attachment belongs
    * @param parent      The parent to which the current attachment belongs
    * @return The view that represents a row in the list of all the attachments
    */
   @Override
   public View getView(final int position, View convertView, ViewGroup parent) {
      /* Retrieve the current attachment to show */
      final AttachmentItem selectedItem = attachments.get(position);

      /* Initialize the components of the row layout */
      RowLayout rowLayout = new RowLayout();
      View rowView = inflater.inflate(R.layout.multimedia_item, null);

      /* Bind the view objects with the views of the layout */
      rowLayout.attachmentName = (TextView) rowView.findViewById(R.id.name);
      rowLayout.attachmentType = (TextView) rowView.findViewById(R.id.type);
      rowLayout.attachmentThumbnails = (ImageView) rowView.findViewById(R.id.thumbnails);
      rowLayout.editButton = (ImageView) rowView.findViewById(R.id.action_edit_attachment);
      rowLayout.deleteButton = (ImageView) rowView.findViewById(R.id.action_delete_attachment);

      /* Set the name of the current attachment */
      rowLayout.attachmentName.setText(selectedItem.getName());

      /* Set the type and the thumbnails of the current attachment */
      switch (selectedItem.getType()) {
         case AttachmentItem.TYPE_AUDIO:
            rowLayout.attachmentType.setText(R.string.attachments_type_audio);
            rowLayout.attachmentThumbnails.setImageBitmap(selectedItem.getThumbnails());
            break;
         case AttachmentItem.TYPE_IMAGE:
            rowLayout.attachmentType.setText(R.string.attachments_type_image);
            rowLayout.attachmentThumbnails.setImageBitmap(selectedItem.getThumbnails());
            break;
         case AttachmentItem.TYPE_VIDEO:
            rowLayout.attachmentType.setText(R.string.attachments_type_video);
            rowLayout.attachmentThumbnails.setImageBitmap(selectedItem.getThumbnails());
            break;
         default:
      }

      /* Set the logic of the edit button used to modify the name of the attachment */
      rowLayout.editButton.setId(position);
      rowLayout.editButton.setVisibility((editState) ? View.VISIBLE : View.GONE);

      rowLayout.editButton.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
            final View selectView = v;

            /* Create and show a dialog to allow the user to modify the name of the selected attachment */
            AlertDialog.Builder alert = new AlertDialog.Builder(notesActivity);
            alert.setTitle(R.string.action_rename);

            final EditText input = new EditText(notesActivity);
            input.setText(selectedItem.getName().substring(0, selectedItem.getName().lastIndexOf(".")));
            input.setSelectAllOnFocus(true);

            InputFilter alphaNumericFilter = new InputFilter() {
               @Override
               public CharSequence filter(CharSequence arg0, int arg1, int arg2, Spanned arg3, int arg4, int arg5)
               {
                  for (int k = arg1; k < arg2; k++) {
                     if (!Character.isLetterOrDigit(arg0.charAt(k))) {
                        return "";
                     }
                  }
                  return null;
               }
            };
            input.setFilters(new InputFilter[]{alphaNumericFilter});

            alert.setView(input);

            alert.setPositiveButton(R.string.ok_button, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int whichButton) {
                  /* Retrieve and show the new name of the selected attachment */
                  String newName = input.getText().toString();
                  String filePath = attachments.get(selectView.getId()).getName();
                  String extension = filePath.substring(filePath.lastIndexOf(".") + 1);

                  /* Check if the inserted name is already assigned at another attachment */
                  boolean isDuplicate = false;
                  for (AttachmentItem item : attachments) {
                     String attachmentName = item.getName();
                     if (attachmentName.equals(newName + "." + extension)) {
                        isDuplicate = true;
                        break;
                     }
                  }

                  /* Check if the new name contains at least one character */
                  if (!newName.isEmpty()) {
                     if (!isDuplicate) { /* Check if the new name is already used */
                        AttachmentsStoringManager.renameFileAppMemory(selectedItem.getName(), newName + "." + extension, currentNote.getId());

                        attachments.get(selectView.getId()).setName(newName + "." + extension);
                        notifyDataSetChanged();
                     } else { /* If the name is already used */
                        Toast.makeText(notesActivity.getApplicationContext(), R.string.toast_duplicate_name, Toast.LENGTH_SHORT).show();
                     }
                  } else { /* If the new name is empty */
                     Toast.makeText(notesActivity.getApplicationContext(), R.string.toast_empty_name, Toast.LENGTH_SHORT).show();
                  }

               }
            });

            alert.setNegativeButton(R.string.cancel_button, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int whichButton) {

               }
            });

            alert.show();

            /* Automatically show the software keyboard */
            InputMethodManager imm = (InputMethodManager) notesActivity.getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

         }
      });

      /* Set the logic of the delete button used to delete the attachment */
      rowLayout.deleteButton.setId(position);
      rowLayout.deleteButton.setVisibility((editState) ? View.VISIBLE : View.GONE);

      rowLayout.deleteButton.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
         /* Retrieve and remove the selected attachment */
         attachments.remove(v.getId());
         tabButton.setText(tabButton.getTag() + " (" + attachments.size() + ")");

         AttachmentsStoringManager.deleteFromAppMemory(selectedItem.getName(), currentNote.getId());

         notifyDataSetChanged();
         }
      });

      return rowView;
   }

}